package com.goodedeeds.domain.impl.db;

import com.goodedeeds.domain.IVendor;
import com.goodedeeds.domain.IVendorCategory;
import com.goodedeeds.domain.IVendorDao;
import com.goodedeeds.domain.resource.Vendor;
import com.youtills.core.auth.IAuthorization;
import com.youtills.core.logging.Logger;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import java.util.HashMap;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: rchiluve
 * Date: 2/23/14
 * Time: 7:48 PM
 * To change this template use File | Settings | File Templates.
 */
public class VendorDao implements IVendorDao {

    private static final Logger LOGGER = Logger.getLogger(VendorDao.class);

    private final SqlSessionFactory sqlSessionFactory;

    private VendorDao() {
        sqlSessionFactory = DomainDao.getInstance().getSqlSessionFactory();
    }

    private static final VendorDao instance = new VendorDao();
    public static VendorDao getInstance(){
        return instance;
    }

    public void saveVendor(IAuthorization authorization, IVendor vendor) {

        if(vendor != null){
            if(vendor.getVendorId() < 1){
                createVendor(authorization, vendor);
            }else {
                updateVendor(authorization, vendor);
            }
        }
    }

    private void updateVendor(IAuthorization authorization, IVendor vendor) {
        SqlSession session = sqlSessionFactory.openSession();
        try {
            session.update("com.goodedeeds.domain.impl.db.vendor-update", vendor);

            if(vendor instanceof Vendor){
                updateVendorCategories(session, (Vendor)vendor);
            }

            session.commit();
        }catch (Exception e){
            LOGGER.error(e);
            session.rollback();
            throw new RuntimeException(e);
        } finally {
            session.close();
        }
    }

    private void createVendor(IAuthorization authorization, IVendor vendor) {
        SqlSession session = sqlSessionFactory.openSession();
        try {
            session.insert("com.goodedeeds.domain.impl.db.vendor-insert", vendor);
            if(vendor instanceof Vendor){
                updateVendorCategories(session, (Vendor)vendor);
            }
            session.commit();
        }catch (Exception e){
            LOGGER.error(e);
            session.rollback();
            throw new RuntimeException(e);
        } finally {
            session.close();
        }
    }

    private void updateVendorCategories(SqlSession session, Vendor vendor){

        session.delete("com.goodedeeds.domain.impl.db.vendor-delete-categories", vendor.getVendorId());
        for(Long categoryId : vendor.getVendorCategoryIds()){
            if(categoryId != null){
                HashMap<String, Long>params = new HashMap<String, Long>(2);
                params.put("vendorId", vendor.getVendorId());
                params.put("categoryId", categoryId);
                session.delete("com.goodedeeds.domain.impl.db.vendor-insert-category", params);
            }
        }
    }

    public IVendor getVendor(IAuthorization authorization, Long vendorId) {
        if(vendorId < 1){
            return new Vendor();
        } else {
            SqlSession session = sqlSessionFactory.openSession();
            try {
                Vendor vendor = session.selectOne(
                        "com.goodedeeds.domain.impl.db.vendor-by-id", vendorId);
                return vendor;
            } finally {
                session.close();
            }
        }
    }

    public List<IVendor> getAllVendors(IAuthorization authorization) {
            SqlSession session = sqlSessionFactory.openSession();
            try {
                List<IVendor> vendors = session.selectList("com.goodedeeds.domain.impl.db.vendors-all");
                return vendors;
            } finally {
                session.close();
            }
    }


    public List<IVendorCategory> getVendorCategories(IAuthorization authorization, Long vendorId) {
            SqlSession session = sqlSessionFactory.openSession();
            try {
                return session.selectList(
                        "com.goodedeeds.domain.impl.db.vendor-categories", vendorId);
            } finally {
                session.close();
            }
    }


    public List<IVendor> searchVendors(IAuthorization authorization, String searchString){

        SqlSession session = sqlSessionFactory.openSession();
        try {

            HashMap<String, String> params = new HashMap<String, String>(1);
            params.put("searchString", searchString);
            return session.selectList(
                    "com.goodedeeds.domain.impl.db.vendor-search", params);
        } finally {
            session.close();
        }
    }
}